package com.googlecode.gwt_control.client.form;

import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FocusListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Olafur Gauti Gudmundsson
 */
public class MultiValueField extends Field {

    private final Panel container;
    private final FlexTable table;
    private final List<String> values;
    private final ValueValidator valueValidator;

    private final Label addLabel;
    private final Panel addPanel;
    private final TextBox valueBox;
    private final Button addBtn;

    private final String valueName;

    public MultiValueField( String id, String title, final String valueName, final ValueValidator valueValidator ) {
        super(id, title, null);
        this.valueName = valueName;
        this.valueValidator = valueValidator;
        values = new ArrayList<String>();

        container = new FlowPanel();
        container.setStyleName("multiValueFieldContainer");

        table = new FlexTable();
        table.setStyleName("multiValueTable");
        table.setCellPadding(0);
        table.setCellSpacing(0);

        // header row
        table.setWidget(0, 0, new Label(""));
        table.setWidget(0, 1, new Label(valueName));
        table.getRowFormatter().addStyleName(0, "headerRow");
        table.getFlexCellFormatter().addStyleName(0, 0, "delColumn");
        table.getFlexCellFormatter().addStyleName(0, 1, "valueColumn");

        container.add(table);

        addLabel = new Label("Add new");
        addLabel.setStyleName("multiValueAddLink");
        addLabel.addStyleName("link");
        addLabel.addClickListener(new ClickListener() {
            public void onClick(Widget sender) {
                toggleAddPanel(true);
            }
        });
        container.add(addLabel);

        addPanel = new FlowPanel();
        addPanel.setStyleName("multiValueAddPanel");

        valueBox = new TextBox();
        valueBox.addFocusListener(new FocusListener() {
            public void onFocus(Widget w) {
                if ( valueBox.getText().trim().equals(valueName) ) {
                    valueBox.setText("");
                }
            }
            public void onLostFocus(Widget w) {
                if ( valueBox.getText().trim().equals("") ) {
                    valueBox.setText(valueName);
                }
            }
        });
        addPanel.add(valueBox);

        final Field field = this;
        addBtn = new Button("add");
        addBtn.addClickListener(new ClickListener() {
            public void onClick(Widget sender) {
                if ( valueValidator.validate(field, valueBox.getText()) ) {
                    addValue(valueBox.getText());
                }
            }
        });
        addPanel.add(addBtn);

        toggleAddPanel(false);
        container.add(addPanel);
    }

    public void setAddLinkText( String text ) {
        addLabel.setText(text);
    }

    public void setAddButtonText( String text ) {
        addBtn.setText(text);
    }

    @Override
    public boolean isEmpty() {
        return values.isEmpty();
    }

    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);
    }

    @Override
    public void addToTable(int rowNumber, FlexTable table) {
        init();
        super.addToTable(rowNumber, table, container);
    }

    private void toggleAddPanel( boolean show ) {
        initAddPanel();
        addPanel.setVisible(show);
        addLabel.setVisible(!show);
    }

    private void initAddPanel() {
        valueBox.setText(valueName);
    }

    private void init() {
        for ( String value : values ) {
            addValue(value);
        }
        initAddPanel();
    }

    public List<String> getValues() {
        return values;
    }

    public void addValue( final String value ) {
        if ( !hasValue(value) ) {
            int newRow = table.getRowCount();

            Label deleteLink = new Label("X");
            deleteLink.setStyleName("deleteLink");
            deleteLink.addStyleName("link");
            deleteLink.addClickListener(new ClickListener() {
                public void onClick(Widget sender) {
                    removeValue(value);
                }
            });

            table.setWidget(newRow, 0, deleteLink);
            table.setWidget(newRow, 1, new Label(value));
            table.getRowFormatter().addStyleName(newRow, "valueRow");

            values.add(value);

            toggleAddPanel(false);
            setError("");
        }
    }

    public void removeValue( String value ) {
        setError("");
        toggleAddPanel(false);

        for ( int row = 1; row < table.getRowCount(); row++ ) {
            if ( ((Label)table.getWidget(row, 1)).getText().equals(value) ) {
                table.removeRow(row);
                break;
            }
        }

        values.remove(value);
    }

    public boolean hasValue( String value ) {
        return values.contains(value);
    }
}
